//#define TEST_API
//#define NO_SDK

using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Internal.Runtime.Models;
using Runtime.Net;
using UnityEngine;
using Internal.Runtime;
using System.Threading.Tasks;

#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
using WeChatWASM;
#elif BYTEDANCEMINIGAME
using TTSDK;
#elif QGMINIGAME
using QGMiniGame;
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
using Internal.Runtime;
#elif GOOGLE_PLAY
using Google;
using GoogleMobileAds;
using GoogleMobileAds.Api;
#else
#endif
#else
#endif
#else
#endif

namespace Runtime.SDK {

    public static partial class DFR_API {

        private static string m_ConnectionExtra;
        private static string m_ConnectionPlatform;

#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
        [System.Runtime.InteropServices.DllImport("__Internal")]
        private static extern string GetNetRemoteSetting();
#elif WEIXINMINIGAME
#elif BYTEDANCEMINIGAME
#elif QGMINIGAME
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
#elif GOOGLE_PLAY
        private static string m_WebClientId = "855471447288-uv6dtbiimi323qlcjvgst8kkcl8bsfrs.apps.googleusercontent.com";
        private static GoogleSignInConfiguration configuration;
        private static string m_GoogleIdToken;
#else
#endif
#else
#endif
#else
#endif

        public delegate void NotifyDelegate();
        public delegate void SystemInfoDelegate(ISystemInfo systemInfo);

        public static IReadOnlyDictionary<string, string> ExtraDataDictionary { get; private set; }

#pragma warning disable CS0067
        public static event SystemInfoDelegate ApplicationShow;
        public static event NotifyDelegate ApplicationHide;
#pragma warning restore CS0067

#pragma warning disable IDE0044 // 添加只读修饰符
        private static DFR_NetRemoteSetting.FeatureSetting m_FeatureSetting = new() {
            Share = true,
            SideBar = true,
            Desktop = true,
            GameClub = true,
            AddMiniProgram = true,
            Subscribe = true,
        };
#pragma warning restore IDE0044 // 添加只读修饰符

        public static bool IsEnabled { get; private set; }

#if TEST_API || !UNITY_EDITOR
        private static string GetShareQuery(Runtime.Models.IDFR_AccountModel accountModel) => Runtime.Models.IDFR_AccountModel.EncodeInviterCode($"inviter={accountModel.ServerID},{accountModel.UID}");

        private static bool m_RewardADShowing = false;
        private static bool m_RewardADIsEnded = false;
        private static bool m_RewardADIsCanceled = true; //只用于协助谷歌admob分支有没有提前关闭广告
        private static string m_UsingRewardADID;
        private static IReadOnlyList<Runtime.Net.DFR_NetRemoteSetting.ShareImageSetting> m_ShareImageList;
        private static bool m_IsStartReported = false;
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
        private static WXRewardedVideoAd m_RewardAD;
#elif BYTEDANCEMINIGAME
        private static ContainerEnv m_Env;
        private static TTRealtimeLogManager m_RewardADLogManager;
#elif QGMINIGAME
        //TODO:留一个TODO标签 这里可能会声明广告变量
        private static QGRewardedVideoAd m_RewardedVideoAd;   
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
#elif GOOGLE_PLAY
        // private RewardBasedVideoAd rewardBasedVideoAd;
        // private RewardingAdBaseClient rewardingAdBaseClient;
#else
#endif
#else
#endif
#else
#endif

        public static async UniTask<ISystemInfo> GetSystemInfo() {
            Runtime.Net.DFR_Net.IS_DEBUG = true;
            var systemInfo = new SystemInfo();
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
            UnityEngine.Application.targetFrameRate = 60;
#elif WEIXINMINIGAME
            IsEnabled = true;
            WX.GetSystemInfo(new GetSystemInfoOption { });
            //WXBase.SetPreferredFramesPerSecond(60);
            UnityEngine.Application.targetFrameRate = 60;
            WX.SetKeepScreenOn(new SetKeepScreenOnOption { keepScreenOn = true });
            WX.OnShow(result => {
                WX.SetKeepScreenOn(new SetKeepScreenOnOption { keepScreenOn = true });
                ApplicationShow?.Invoke(null);
            });
            WX.OnHide(result => {
                ApplicationHide?.Invoke();
            });
            var accountModel = DFR_Core.DataCenter.Models.Account;
            WXBase.OnShareAppMessage(new WXShareAppMessageParam {
                query = GetShareQuery(accountModel),
            }, action => {
                if (m_ShareImageList?.Count > 0) {
                    var randamIndex = UnityEngine.Random.Range(0, m_ShareImageList.Count);
                    var shareImage = m_ShareImageList[randamIndex];
                    var param = new WXShareAppMessageParam {
                        query = GetShareQuery(accountModel),
                        imageUrlId = shareImage.Key,
                        imageUrl = shareImage.URL,
                    };
                    action.Invoke(param);
                }
            });
            var launchOptions = WX.GetLaunchOptionsSync();
            if (launchOptions != null) {
                if (launchOptions.query.TryGetValue("inviter", out var inviterCode)) {
                    DFR_Core.DataCenter.Models.Account.AsSetter().SetInviterCode(inviterCode);
                }
            }
#elif BYTEDANCEMINIGAME
            IsEnabled = true;
            var isInit = false;
            TT.InitSDK((code, env) => {
                isInit = true;
                m_Env = env;
            });
            await KHBD.Context.WaitUntil(() => isInit);
            systemInfo.LaunchFrom = m_Env.GetLaunchFrom();
            systemInfo.Location = m_Env.GetLocation();
            UnityEngine.Application.targetFrameRate = 60;
            TT.SetKeepScreenOn(true);
            var lifeCycle = TT.GetAppLifeCycle();
            lifeCycle.OnShow += result => {
                TT.SetKeepScreenOn(true);
                result.TryGetValue("launchFrom", out var onShowLaunchFrom);
                UnityEngine.Debug.Log($"launchFrom:{onShowLaunchFrom}");
                result.TryGetValue("location", out var onShowLocation);
                UnityEngine.Debug.Log($"location:{onShowLocation}");
                var onShowSystemInfo = new SystemInfo {
                    LaunchFrom = onShowLaunchFrom?.ToString(),
                    Location = onShowLocation?.ToString(),
                };
                ApplicationShow?.Invoke(onShowSystemInfo);
            };
            lifeCycle.OnHide += () => {
                ApplicationHide?.Invoke();
            };
            var accountModel = DFR_Core.DataCenter.Models.Account;
            TT.OnShareAppMessage(option => {
                if (m_ShareImageList?.Count > 0) {
                    var randamIndex = UnityEngine.Random.Range(0, m_ShareImageList.Count);
                    var shareImage = m_ShareImageList[randamIndex];
                    var json = new TTSDK.UNBridgeLib.LitJson.JsonData {
                        ["templateId"] = shareImage.Key,
                        ["query"] = GetShareQuery(accountModel),
                    };
                    return new TTShare.ShareParam(json, successCallback: null, failedCallback: errMsg => UnityEngine.Debug.LogWarning(errMsg), cancelledCallback: null);
                }
                return null;
            });
            var launchOptions = m_Env.GetLaunchOptionsSync();
            if (launchOptions != null) {
                if (launchOptions.Query.TryGetValue("inviter", out var inviterCode)) {
                    DFR_Core.DataCenter.Models.Account.AsSetter().SetInviterCode(inviterCode);
                }
            }
#elif QGMINIGAME
            IsEnabled = true;
            UnityEngine.Application.targetFrameRate = 60;
            QG.SetKeepScreenOn(true);
            QG.OnShow((response) => {
                QG.SetKeepScreenOn(true);
                ApplicationShow?.Invoke(null);
            });
            QG.OnHide((response) => {
                ApplicationHide?.Invoke();
            });

            var accountModel = DFR_Core.DataCenter.Models.Account;
            QG.GetEnterOptionsSync(
                (msg) => {
                    UnityEngine.Debug.Log("success " + JsonUtility.ToJson(msg));
                    if (msg.data.query.inviterID != null)
                        DFR_Core.DataCenter.Models.Account.AsSetter().SetInviterCode(msg.data.query.inviterID);
                },
                (msg) => {
                    UnityEngine.Debug.Log("fail");
                }
            );
#else
            UnityEngine.Application.targetFrameRate = 60;
#endif
#elif UNITY_ANDROID
#if NO_SDK
            UnityEngine.Application.targetFrameRate = 60;
#elif GOOGLE_PLAY
            UnityEngine.Application.targetFrameRate = 60;
            IsEnabled = true;
#else
#endif
#else
            UnityEngine.Application.targetFrameRate = 60;
#endif
#else
            UnityEngine.Application.targetFrameRate = 300;
#endif

#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
            var netRemoteSettingJson = GetNetRemoteSetting();
            var netRemoteSetting = Newtonsoft.Json.JsonConvert.DeserializeObject<Runtime.Net.DFR_NetRemoteSetting>(netRemoteSettingJson);
            Runtime.Net.DFR_Net.ENV_TAG = netRemoteSetting.NoSDKEnvTag;
#elif WEIXINMINIGAME
            var netRemoteSettingPrefix = $"web_wechat";
            var productName = UnityEngine.Application.productName;
            var cdnSettings = UnityEngine.Resources.Load<Runtime.Settings.DFR_CDNProjectSettings>($"DFR/{nameof(Runtime.Settings.DFR_CDNProjectSettings)}");
            var netRemoteSettingsJson = await Runtime.Net.DFR_NetWebRequest.Get(cdnSettings.Settings);
            var netRemoteSettings = Newtonsoft.Json.JsonConvert.DeserializeObject<Runtime.Net.DFR_NetRemoteSettings>(netRemoteSettingsJson);
            var netRemoteSetting = netRemoteSettings.Get($"{netRemoteSettingPrefix}_{productName}_v{UnityEngine.Application.version}");
            m_ShareImageList = netRemoteSetting.ShareImageList;
            if (!string.IsNullOrWhiteSpace(netRemoteSetting.RewardAD)) {
                m_UsingRewardADID = netRemoteSetting.RewardAD;
                m_RewardAD = WXBase.CreateRewardedVideoAd(new WXCreateRewardedVideoAdParam { adUnitId = m_UsingRewardADID, multiton = true });
                m_RewardAD.OnClose(OnRewardADClose);
            }
            DFR_Core.DataCenter.Models.Application.AsSetter().SetID(netRemoteSetting.APPID);
            DFR_Core.DataCenter.Models.Application.AsSetter().SetName(netRemoteSetting.AppName);
            m_ConnectionPlatform = netRemoteSetting.Connection.Platform;
            ExtraDataDictionary = netRemoteSetting.ExtraDataDictionary;
#elif BYTEDANCEMINIGAME
            var netRemoteSettingPrefix = $"web_bytedance";
            var productName = UnityEngine.Application.productName;
            var cdnSettings = UnityEngine.Resources.Load<Runtime.Settings.DFR_CDNProjectSettings>($"DFR/{nameof(Runtime.Settings.DFR_CDNProjectSettings)}");
            var netRemoteSettingsJson = await Runtime.Net.DFR_NetWebRequest.Get(cdnSettings.Settings);
            var netRemoteSettings = Newtonsoft.Json.JsonConvert.DeserializeObject<Runtime.Net.DFR_NetRemoteSettings>(netRemoteSettingsJson);
            var netRemoteSetting = netRemoteSettings.Get($"{netRemoteSettingPrefix}_{productName}_v{UnityEngine.Application.version}");
            m_ShareImageList = netRemoteSetting.ShareImageList;
            if (!string.IsNullOrWhiteSpace(netRemoteSetting.RewardAD)) {
                m_UsingRewardADID = netRemoteSetting.RewardAD;
            }
            DFR_Core.DataCenter.Models.Application.AsSetter().SetID(netRemoteSetting.APPID);
            DFR_Core.DataCenter.Models.Application.AsSetter().SetName(netRemoteSetting.AppName);
            m_ConnectionPlatform = netRemoteSetting.Connection.Platform;
            ExtraDataDictionary = netRemoteSetting.ExtraDataDictionary;
#elif QGMINIGAME
            //TODO:留一个TODO标签
            var netRemoteSettingPrefix = $"web_vivo";
            var productName = UnityEngine.Application.productName;
            var cdnSettings = UnityEngine.Resources.Load<Runtime.Settings.DFR_CDNProjectSettings>($"DFR/{nameof(Runtime.Settings.DFR_CDNProjectSettings)}");
            var netRemoteSettingsJson = await Runtime.Net.DFR_NetWebRequest.Get(cdnSettings.Settings);
            var netRemoteSettings = Newtonsoft.Json.JsonConvert.DeserializeObject<Runtime.Net.DFR_NetRemoteSettings>(netRemoteSettingsJson);
            var netRemoteSetting = netRemoteSettings.Get($"{netRemoteSettingPrefix}_{productName}_v{UnityEngine.Application.version}");
            m_ShareImageList = netRemoteSetting.ShareImageList;
            if (!string.IsNullOrWhiteSpace(netRemoteSetting.RewardAD)) {
                m_UsingRewardADID = netRemoteSetting.RewardAD;
                // m_RewardedVideoAd = QG.CreateRewardedVideoAd(new QGCommonAdParam() {
                //     posId = "b56295fe4cf244698a4f1419e9d31331"
                // });
            }
            DFR_Core.DataCenter.Models.Application.AsSetter().SetID(netRemoteSetting.APPID);
            DFR_Core.DataCenter.Models.Application.AsSetter().SetName(netRemoteSetting.AppName);
            m_ConnectionPlatform = netRemoteSetting.Connection.Platform;
            ExtraDataDictionary = netRemoteSetting.ExtraDataDictionary;
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
            var netRemoteSetting = GetRemoteSetting();
#elif GOOGLE_PLAY
            var netRemoteSetting = GetRemoteSetting();
            //初始化的逻辑应该只用执行一次，故没有写在下方的ShowRewardAd方法中，因为那个方法看起来会多次调用
            MobileAds.Initialize((InitializationStatus initStatus) => {
                //This callback is called once the MobileAds SDK is initialized.
                UnityEngine.Debug.Log("已经完成初始化广告SDK");
            });
            DFR_Core.DataCenter.Models.Application.AsSetter().SetID(netRemoteSetting.APPID);
#else
#endif
#elif UNITY_STANDALONE_WIN
            var netRemoteSettingsJson = System.IO.File.ReadAllText(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(UnityEngine.Application.dataPath), "NetRemoteSettings.json"));
            var netRemoteSettings = Newtonsoft.Json.JsonConvert.DeserializeObject<Runtime.Net.DFR_NetRemoteSettings>(netRemoteSettingsJson);
            var netRemoteSetting = netRemoteSettings.Get("develop");
#else
#endif
            UnityEngine.Debug.Log(netRemoteSetting);
            m_ConnectionExtra = netRemoteSetting.Connection.Extra;
            UnityEngine.Debug.Log(m_ConnectionExtra);
            m_ConnectionPlatform = netRemoteSetting.Connection.Platform;
            UnityEngine.Debug.Log(m_ConnectionPlatform);
            Runtime.Net.DFR_Net.CONNECTION_URL = netRemoteSetting.Connection.URL;
            Runtime.Net.DFR_Net.CONNECTION_URL = netRemoteSetting.Connection.URL;
            Runtime.Net.DFR_Net.CONNECTION_PLATFORM = netRemoteSetting.Connection.Platform;
            Runtime.Net.DFR_Net.CDN_URL = netRemoteSetting.CDNURL;
            Runtime.Net.DFR_Net.IS_DEBUG = netRemoteSetting.IsDebug;
            Runtime.Net.DFR_Net.IS_DEBUG_AD = netRemoteSetting.IsDebugAD;
            if (netRemoteSetting.Feature != null) {
                m_FeatureSetting = netRemoteSetting.Feature;
            } else {
                m_FeatureSetting = new DFR_NetRemoteSetting.FeatureSetting {
                    Share = false,
                    SideBar = false,
                    Desktop = false,
                    GameClub = false,
                    AddMiniProgram = false,
                };
            }
#else
#endif
            await UniTask.Yield();
            return systemInfo;
        }

        public static async UniTask<ILoginResult> Login() {
            var login = new LoginResult();
            var feature = DFR_Core.DataCenter.Models.Feature as IDFR_FeatureModelInternal;
            feature.AddShare(m_FeatureSetting.Share);
            feature.AddSideBar(m_FeatureSetting.SideBar);
            feature.AddDesktop(m_FeatureSetting.Desktop);
            feature.AddGameClub(m_FeatureSetting.GameClub);
            feature.AddMiniProgram(m_FeatureSetting.AddMiniProgram);
            feature.AddSubscribe(m_FeatureSetting.Subscribe);
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
            (DFR_Core.Application as IDFR_ApplicationInternal).SetVersion($"v{UnityEngine.Application.version}");
            login.Extra = m_ConnectionExtra;
            await UniTask.Yield();
#elif WEIXINMINIGAME
            var isDone = false;
            var accountInfo = WX.GetAccountInfoSync();
            var envVersion = accountInfo == null ? "trial" : accountInfo.miniProgram.envVersion;
            if (envVersion == "release") {
                (DFR_Core.Application as IDFR_ApplicationInternal).SetVersion(accountInfo.miniProgram.version);
                envVersion = string.Empty;
            } else {
                (DFR_Core.Application as IDFR_ApplicationInternal).SetVersion($"v{UnityEngine.Application.version}");
                envVersion = "trial";
            }

            WX.Login(new LoginOption {
                success = callback => {
                    login.Platform = m_ConnectionPlatform;
                    login.Token = callback.code;
                    login.EnvVersion = envVersion;
                    login.Extra = m_ConnectionExtra;
                    isDone = true;
                },
                fail = callback => {
                    UnityEngine.Debug.LogError(callback.errMsg);
                    isDone = true;
                }
            });
            await KHBD.Context.WaitUntil(() => isDone);
#elif BYTEDANCEMINIGAME
            if (!CanIUse.AddShortcut) {
                feature.AddDesktop(false);
            }
            (DFR_Core.Application as IDFR_ApplicationInternal).SetVersion(TT.GameVersion);
            var isDone = false;
            var isForce = true;
            var isRelease = TT.GetSystemInfo().hostName != "devtools" && m_Env.GetVersionType() == VersionType.Release;
            var envVersion = isRelease ? "release" : "trial";
            if (envVersion == "release") {
                envVersion = string.Empty;
            }
            TT.Login(
                (code, anonymousCode, isLogin) => {
                    login.Platform = m_ConnectionPlatform;
                    login.Token = code;
                    login.EnvVersion = envVersion;
                    login.Extra = m_ConnectionExtra;
                    isDone = true;
                },
                (msg) => {
                    UnityEngine.Debug.Log(msg);
                    isDone = true;
                }, isForce);
            await KHBD.Context.WaitUntil(() => isDone);
            m_RewardADLogManager = TT.GetRealtimeLogManager(new GetRealtimeManagerParam { SyncToConsole = true });
            m_RewardADLogManager.AddFilterMsg("RewardAD");
#elif QGMINIGAME
            //TODO:留一个TODO标签 登录
            var isDone = false;
            var infoSync = QG.GetSystemInfoSync();
            UnityEngine.Debug.Log("原始JSON字符串: " + infoSync);
            var response = JsonUtility.FromJson<SystemInfoData>(infoSync);
            string envVersion = "trial";
            UnityEngine.Debug.Log("默认为trail");
            if (response != null && response != null) {
                if (response.miniGame != null) {
                    UnityEngine.Debug.Log("当前的构建类型为：" + response.miniGame.buildType);
                    if (response.miniGame.buildType == "release") {
                        envVersion = "release";
                        UnityEngine.Debug.Log("正式版");
                    }
                }
            }

            if (envVersion == "release") {
                (DFR_Core.Application as IDFR_ApplicationInternal).SetVersion(envVersion);
                envVersion = string.Empty;
            } else {
                (DFR_Core.Application as IDFR_ApplicationInternal).SetVersion($"v{UnityEngine.Application.version}");
                envVersion = "trial";
            }

            QG.Login(
                (msg) => {
                    UnityEngine.Debug.Log("成功？Login输出");
                    login.Platform = m_ConnectionPlatform;
                    login.Token = msg.data.token;
                    login.EnvVersion = envVersion;
                    login.Extra = m_ConnectionExtra;
                    UnityEngine.Debug.Log($"platform:{login.Platform}");
                    UnityEngine.Debug.Log($"token:{login.Token}");
                    UnityEngine.Debug.Log($"envVersion:{login.EnvVersion}");
                    UnityEngine.Debug.Log($"extra:{login.Extra}");
                    isDone = true;
                },
                (msg) => {
                    UnityEngine.Debug.Log("失败？Login输出");
                    UnityEngine.Debug.Log(msg);
                    isDone = true;
                }
            );
            await KHBD.Context.WaitUntil(() => isDone);
#else
            (DFR_Core.Application as IDFR_ApplicationInternal).SetVersion($"v{UnityEngine.Application.version}");
            await UniTask.Yield();
#endif
#elif UNITY_ANDROID
#if NO_SDK
            (DFR_Core.Application as IDFR_ApplicationInternal).SetVersion($"v{UnityEngine.Application.version}");
            login.Extra = m_ConnectionExtra;
            await UniTask.Yield();
#elif GOOGLE_PLAY
            configuration = new GoogleSignInConfiguration {
                    WebClientId = m_WebClientId,
                    RequestIdToken = true
            };
            (DFR_Core.Application as IDFR_ApplicationInternal).SetVersion($"v{UnityEngine.Application.version}");
            GoogleSignIn.Configuration = configuration;
            GoogleSignIn.Configuration.UseGameSignIn = false;
            GoogleSignIn.Configuration.RequestIdToken = true;
            //AddStatusText("Calling SignIn");

            await GoogleSignIn.DefaultInstance.SignIn().ContinueWith(OnAuthenticationFinished);
            login.Platform = m_ConnectionPlatform;
            login.Token = m_GoogleIdToken;
            UnityEngine.Debug.Log(m_GoogleIdToken);
            login.EnvVersion = string.Empty;
            login.Extra = m_ConnectionExtra;
            //await UniTask.Yield();
#else
#endif
#else
            (DFR_Core.Application as IDFR_ApplicationInternal).SetVersion($"v{UnityEngine.Application.version}");
            await UniTask.Yield();
#endif
#else
            await UniTask.Yield();
#endif
            return login;
        }

        public static void ReportStart() {
#if TEST_API || !UNITY_EDITOR
            if (m_IsStartReported) {
                return;
            }
            m_IsStartReported = true;
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
            WXBase.ReportGameStart();
#elif BYTEDANCEMINIGAME
            var param = new TTSDK.UNBridgeLib.LitJson.JsonData {
                ["sceneId"] = 7001,
                ["costTime"] = (long)(UnityEngine.Time.realtimeSinceStartup * 1000)
            };
            TT.ReportScene(param, (res) => {
                UnityEngine.Debug.Log($"ReportScene success: {res.ToJson()}");
            }, (code, msg) => {
                UnityEngine.Debug.LogError($"ReportScene fail: code:{code}, msg:{msg}");
            });
#elif QGMINIGAME
            //TODO:留一个TODO标签 这里好像是上报场景数据的 暂时没内容
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
#elif GOOGLE_PLAY
#else
#endif
#else
#endif
#else
#endif
        }

#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
        // 关闭广告事件监听
        private static void OnRewardADClose(WXRewardedVideoAdOnCloseResponse res) {
            // 小于 2.1.0 的基础库版本，res 是一个 undefined
            if ((res != null && res.isEnded) || res == null) {
                // 正常播放结束，可以下发游戏奖励
                m_RewardADIsEnded = true;
            } else {
                // 播放中途退出，不下发游戏奖励
                m_RewardADIsEnded = false;
            }
            m_RewardADShowing = false;
        }
#elif BYTEDANCEMINIGAME
#elif QGMINIGAME
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
        private static DFR_NetRemoteSetting GetRemoteSetting() {
            return UnityEngine.Resources.Load<DFR_NetRemoteSettingDefault>(nameof(DFR_NetRemoteSettingDefault)).Setting;
        }
#elif GOOGLE_PLAY
        private static DFR_NetRemoteSetting GetRemoteSetting() {
            UnityEngine.Debug.Log("进入了这个获取RemoteSetting的方法");
            return UnityEngine.Resources.Load<DFR_NetRemoteSettingDefault>(nameof(DFR_NetRemoteSettingDefault)).Setting;
        }
        
        private static void OnAuthenticationFinished(Task<GoogleSignInUser> task) {
            UnityEngine.Debug.Log("进入了验证登录的方法");
            if (task.IsFaulted) {
                using (IEnumerator<System.Exception> enumerator = task.Exception.InnerExceptions.GetEnumerator()) {
                    if (enumerator.MoveNext()) {
                        GoogleSignIn.SignInException error = (GoogleSignIn.SignInException)enumerator.Current;
                        UnityEngine.Debug.Log("Got Error: " + error.Status + " " + error.Message);
                    } else {
                        UnityEngine.Debug.Log("Got Unexpected Exception?!?" + task.Exception);
                    }
                }
            } else if (task.IsCanceled) {
                UnityEngine.Debug.Log("Canceled");
            } else {
                UnityEngine.Debug.Log("Welcome: " + task.Result.DisplayName + "!");
                UnityEngine.Debug.Log("idToken是:" + task.Result.IdToken);
                m_GoogleIdToken = task.Result.IdToken;
            }
        }
#else
#endif
#else
#endif
#else
#endif

#if TEST_API || !UNITY_EDITOR
        public readonly struct ADInfo {
            public string ADID { get; init; }
            public bool State { get; init; }
            public int Count { get; init; }
        }

        public static async UniTask<ADInfo> ShowRewardAd(System.Action<ADInfo> onLoad = null) {
            if (m_RewardADShowing) {
                return new ADInfo { State = false };
            }
            m_RewardADShowing = true;
            m_RewardADIsEnded = false;
            m_RewardADIsCanceled = true;
            var count = 0;
#if UNITY_WEBGL
#if NO_SDK
            count = await RewardADEnd();
#elif WEIXINMINIGAME
            //var isFailed = false;
            if (m_RewardAD != null) {
                m_RewardAD.Load(_ => {
                    m_RewardAD.Show(failed: response => {
                        UnityEngine.Debug.LogWarning(response.errMsg);
                        m_RewardADShowing = false;
                        //isFailed = true;
                    });
                }, failed: response => {
                    UnityEngine.Debug.LogWarning(response.errMsg);
                    m_RewardADShowing = false;
                    m_RewardADIsEnded = true; //有广告组件，但是没有加载到广告，所以给了true
                    //isFailed = true;
                });
            } else {
                UnityEngine.Debug.LogWarning("没有广告组件o");
                m_RewardADShowing = false;
                //isFailed = true;
                m_RewardADIsEnded = true;
            }
            await KHBD.Context.WaitUntil(() => !m_RewardADShowing);
            // if (m_RewardADIsEnded && !isFailed) {
            if (m_RewardADIsEnded) {
                count = 1;
            }
#elif BYTEDANCEMINIGAME
            if(m_UsingRewardADID != null) {
                var rewardAD = TT.CreateRewardedVideoAd(m_UsingRewardADID, closeCallback: (bool isEnded, int number) => {
                    m_RewardADLogManager.Log($"[RewardAD] {nameof(isEnded)}:{isEnded}, {nameof(number)}:{number}");
                    m_RewardADIsEnded = isEnded;
                    m_RewardADShowing = false;
                    count += number;
                }, errCallback: (code, message) => {
                    m_RewardADLogManager.Error($"[RewardAD] {nameof(code)}:{code}, {nameof(message)}:{message}");
                    onLoad?.Invoke(new ADInfo { ADID = m_UsingRewardADID, State = false });
                    m_RewardADIsEnded = true; //目的是就算广告有误，也不卡住用户
                    m_RewardADShowing = false;
                });
                rewardAD.OnLoad += () => {
                    m_RewardADLogManager.Log("[RewardAD] Loaded");
                    onLoad?.Invoke(new ADInfo { ADID = m_UsingRewardADID, State = true });
                    rewardAD.Show();
                };
                m_RewardADLogManager.Log("[RewardAD] Request");
                rewardAD.Load();
                await KHBD.Context.WaitUntil(() => !m_RewardADShowing);
                rewardAD?.Destroy();
            } else {
                m_RewardADIsEnded = true;
                count = 1;
            }
#elif QGMINIGAME
            //TODO:留一个TODO标签 创建广告
            //第一次创建视频广告对象时，已自动加载一次广告
            if (m_RewardedVideoAd == null)
            {
                UnityEngine.Debug.Log("当前的激励广告是空的，我需要创建一个");
                m_RewardedVideoAd = QG.CreateRewardedVideoAd(new QGCommonAdParam() {
                    posId = "b56295fe4cf244698a4f1419e9d31331"
                });
            }

            UnityEngine.Debug.Log("我尝试加载激励广告");
            m_RewardedVideoAd.Load(
                (msg) => {
                    Debug.Log("激励视频广告加载成功 " + JsonUtility.ToJson(msg));
                },
                (msg) => {
                    Debug.Log("激励视频广告加载失败 " + msg.errMsg);
                    m_RewardADShowing = false;
                }
            );

            //广告Load完成的时候，OnLoad就会触发
            m_RewardedVideoAd.OnLoad(() => {
                //视频广告组件默认是隐藏的，调用show方法展示广告
                m_RewardedVideoAd.Show(
                    (msg) => {
                        Debug.Log("激励视频广告展示完成 " + JsonUtility.ToJson(msg));
                    },
                    (msg) => {
                        Debug.Log("激励视频广告展示失败 " + msg.errMsg);
                        m_RewardADShowing = false;
                    }
                );
            });

            m_RewardedVideoAd.OnClose((QGRewardedVideoResponse msg) => {
                if (msg.isEnded) {
                    Debug.Log("正常播放结束，可以下发奖励，播放成功");
                    m_RewardADShowing = false;
                    m_RewardADIsEnded = true;
                } else {
                    Debug.Log("播放中途退出，不下发奖励");
                    m_RewardADShowing = false;
                    m_RewardADIsEnded = false;
                }
            });

            m_RewardedVideoAd.OnError(
                msg => {
                    Debug.Log("激励视频广告出现错误 " + msg.errMsg);
                    m_RewardADShowing = false;
                    m_RewardADIsEnded = true;
                }
            );
            await KHBD.Context.WaitUntil(() => !m_RewardADShowing);
            if(m_RewardADIsEnded) {
                count = 1;
            }
#else
            count = await RewardADEnd();
#endif
#elif UNITY_ANDROID
#if NO_SDK
            count = await RewardADEnd();
#elif GOOGLE_PLAY
            var adRequest = new AdRequest();
            RewardedAd.Load("ca-app-pub-9546414920294035/5825371157", adRequest, (RewardedAd ad, LoadAdError error) => {
                if (error != null) {
                    UnityEngine.Debug.LogWarning(error.GetResponseInfo());
                    m_RewardADShowing = false;
                    m_RewardADIsEnded = true; //没有加载到广告，这里给true是因为看到抖音的分支中有写："就算广告有误，也不卡住用户"
                }
                UnityEngine.Debug.Log("广告加载成功");
                if (ad != null && ad.CanShowAd()) {
                    ad.Show((Reward reward) =>
                    {
                        UnityEngine.Debug.Log("广告展示成功");
                        m_RewardADShowing = false;
                        m_RewardADIsCanceled = false;
                        //至此，当前的激励广告应该不会再使用了，所以我要对其进行清理，这会通知插件已不再使用该对象，且可回收它占用的内存
                        if (ad != null) {
                            UnityEngine.Debug.Log("销毁了当前广告");
                            ad.Destroy();
                        }
                    });
                    ad.OnAdFullScreenContentFailed += (AdError error) =>
                    {
                        UnityEngine.Debug.Log("广告展示全屏内容失败了，可能是拉取过程中游戏失去了焦点");
                        m_RewardADShowing = false;
                        m_RewardADIsEnded = false;
                    };
                    ad.OnAdFullScreenContentClosed += () =>
                    {
                        UnityEngine.Debug.Log("当广告关闭全屏内容时触发");
                        m_RewardADShowing = false;
                        if(m_RewardADIsCanceled == false)
                            m_RewardADIsEnded = true;
                        else
                            m_RewardADIsEnded = false;
                    };
                }
            });
            await KHBD.Context.WaitUntil(() => !m_RewardADShowing);
            if (m_RewardADIsEnded) {
                count = 1;
            }
            //count = await RewardADEnd();
#else
#endif
#else
            count = await RewardADEnd();
#endif
            var result = new ADInfo {
#else
#endif

#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
                ADID = m_UsingRewardADID,
#elif BYTEDANCEMINIGAME
                ADID = m_UsingRewardADID,
#elif QGMINIGAME
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
#elif GOOGLE_PLAY
#else
#endif
#else
#endif
                State = m_RewardADIsEnded,
                Count = count,
            };
            return result;
        }

        private static async UniTask<int> RewardADEnd() {
            m_RewardADIsEnded = true;
            await UniTask.Yield();
            return 1;
        }
#else
#endif


        public static async UniTask<bool> Share() {
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
            await UniTask.Yield();
            return true;
#elif WEIXINMINIGAME
            var accountModel = DFR_Core.DataCenter.Models.Account;
            if (m_ShareImageList?.Count > 0) {
                var randamIndex = UnityEngine.Random.Range(0, m_ShareImageList.Count);
                var shareImage = m_ShareImageList[randamIndex];
                WX.ShareAppMessage(new ShareAppMessageOption {
                    query = GetShareQuery(accountModel),
                    imageUrlId = shareImage.Key,
                    imageUrl = shareImage.URL,
                });
            } else {
                WX.ShareAppMessage(new ShareAppMessageOption {
                    query = GetShareQuery(accountModel),
                });
            }
            await UniTask.Yield();
            return true;
#elif BYTEDANCEMINIGAME
            var accountModel = DFR_Core.DataCenter.Models.Account;
            var json = new TTSDK.UNBridgeLib.LitJson.JsonData() {
                ["query"] = GetShareQuery(accountModel),
            };
            if (m_ShareImageList?.Count > 0) {
                var randamIndex = UnityEngine.Random.Range(0, m_ShareImageList.Count);
                var shareImage = m_ShareImageList[randamIndex];
                json["templateId"] = shareImage.Key;
            }
            var isDone = false;
            var isSuccess = false;
            TT.ShareAppMessage(json, failedCallback: errMsg => {
                UnityEngine.Debug.LogWarning(errMsg);
                isDone = true;
            }, successCallback: _ => {
                isDone = true;
                isSuccess = true;
            }, cancelledCallback: () => isDone = true);
            await KHBD.Context.WaitUntil(() => isDone);
            return isSuccess;
#elif QGMINIGAME
            if (m_ShareImageList?.Count > 0) {
                var randamIndex = UnityEngine.Random.Range(0, m_ShareImageList.Count);
                var shareImage = m_ShareImageList[randamIndex];
                QG.Share(
                    (msg) => {
                        UnityEngine.Debug.Log("分享成功 " + JsonUtility.ToJson(msg));
                    },
                    (msg) => {
                        UnityEngine.Debug.LogWarning("分享失败 " + JsonUtility.ToJson(msg));
                    },
                    (msg) => {
                        UnityEngine.Debug.Log("分享取消 " + JsonUtility.ToJson(msg));
                    }
                );
            } else {
                QG.Share(
                    (msg) => {
                        UnityEngine.Debug.Log("分享成功 " + JsonUtility.ToJson(msg));
                    },
                    (msg) => {
                        UnityEngine.Debug.LogWarning("分享失败 " + JsonUtility.ToJson(msg));
                    },
                    (msg) => {
                        UnityEngine.Debug.Log("分享取消 " + JsonUtility.ToJson(msg));
                    }
                );
            }
            await UniTask.Yield();
            return true;
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
            await UniTask.Yield();
            return true;
#elif GOOGLE_PLAY
            await UniTask.Yield();
            return true;
#else
#endif
#else
            await UniTask.Yield();
            return true;
#endif
#else
            await UniTask.Yield();
            return true;
#endif
        }

        public static void OpenSideBar() {
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
#elif BYTEDANCEMINIGAME
            var data = new TTSDK.UNBridgeLib.LitJson.JsonData {
                ["scene"] = "sidebar", //TTSideBar.SceneEnum.SideBar,
            };
            TT.NavigateToScene(data, success: () => {
                UnityEngine.Debug.Log("navigate to scene success");
            }, complete: () => {
                UnityEngine.Debug.Log("navigate to scene complete");
            }, (errCode, errMsg) => {
                UnityEngine.Debug.LogWarning($"navigate to scene error, errCode:{errCode}, errMsg:{errMsg}");
            });
#elif QGMINIGAME
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
#elif GOOGLE_PLAY
#else
#endif
#else
#endif
#else
#endif
        }
        public static async UniTask<bool> CheckIsAddedToMyMiniProgram() {
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
            await UniTask.Yield();
            return false;
#elif WEIXINMINIGAME
            var completionSource = new UniTaskCompletionSource<bool>();
            CheckIsAddedToMyMiniProgramOption option = new CheckIsAddedToMyMiniProgramOption
            {
                success = (res) =>
                {
                    UnityEngine.Debug.Log("调用检查是否添加小程序的接口成功");
                    UnityEngine.Debug.Log("是否添加小程序：" + res.added);
                    completionSource.TrySetResult(res.added);
                },
                fail = (errMsg) =>
                {
                    UnityEngine.Debug.Log("调用检查是否添加小程序的接口失败");
                    completionSource.TrySetResult(false);
                }
            };
            WX.CheckIsAddedToMyMiniProgram(option);
            return await completionSource.Task;
#elif BYTEDANCEMINIGAME
            await UniTask.Yield();
            return false;
#elif QGMINIGAME
            await UniTask.Yield();
            return false;
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
            await UniTask.Yield();
            return false;
#elif GOOGLE_PLAY
            await UniTask.Yield();
            return false;
#else
#endif
#else
            await UniTask.Yield();
            return false;
#endif
#else
            await UniTask.Yield();
            return false;
#endif
        }
    }
}

